package system

import (
	"context"
	"gf_blog_admin/internal/dao"
	"gf_blog_admin/internal/model"
	"gf_blog_admin/internal/service"
	"gf_blog_admin/utility/casbinPolicy"
	"gf_blog_admin/utility/storager"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gfile"
)

type sSysConfig struct{}

func init() {
	service.RegisterSysConfig(NewSysConfig())
}

func NewSysConfig() *sSysConfig {
	return &sSysConfig{}
}

func (s *sSysConfig) InitConfig(ctx context.Context) (err error) {
	// 初始化权限
	if err = casbinPolicy.InitEnforcer(ctx); err != nil {
		g.Log().Error(ctx, err)
	}

	// 初始化上传配置
	var conf *storager.UploadConfig
	err = g.Cfg().MustGet(ctx, "upload").Scan(&conf)
	if err != nil {
		g.Log().Error(ctx, err)
	}
	// 创建本地资源路径
	if conf.LocalConfig.Path != "" && !gfile.IsDir(conf.LocalConfig.Path) {
		if err = gfile.Mkdir(conf.LocalConfig.Path); err != nil {
			g.Log().Error(ctx, err)
		}
	}
	storager.SetConfig(conf)
	return
}

func (s *sSysConfig) GetConfig(ctx context.Context, confKey string) (map[string]interface{}, error) {
	var (
		out map[string]interface{}
		cls = dao.BlSysConfig.Columns()
	)

	conf, err := dao.BlSysConfig.Ctx(ctx).
		Where(cls.ConfKey, confKey).
		Fields(cls.ConfValue).
		Value()
	if err != nil {
		return nil, err
	}
	if conf != nil {
		out = conf.Map()
	}
	return out, nil
}

func (s *sSysConfig) GetData(ctx context.Context, confKeys []string) (out map[string]interface{}, err error) {
	var (
		cls    = dao.BlSysConfig.Columns()
		result = make([]*model.ConfigItem, 0)
	)

	err = dao.BlSysConfig.Ctx(ctx).
		WhereIn(cls.ConfKey, confKeys).
		Fields(cls.ConfKey, cls.ConfValue).
		Scan(&result)
	if err != nil {
		return nil, err
	}
	if result != nil {
		for _, v := range result {
			out[v.ConfKey] = v.ConfValue
		}
	}
	return
}

func (s *sSysConfig) Update(ctx context.Context, in *model.ConfigFormInput) (err error) {
	err = dao.BlSysConfig.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.BlSysConfig.Ctx(ctx).Data(in).Save()
		return err
	})
	return
}
